#ifndef UI_MULTIPLEXER_H_
#define UI_MULTIPLEXER_H_

#include "interfaces/Useroutputinterface.h"
#include <boost/shared_ptr.hpp>
#include <boost/asio/ip/tcp.hpp>
#include <boost/asio/local/stream_protocol.hpp>
#include <boost/asio/io_service.hpp>
#include <boost/utility.hpp>
#include <vector>

using namespace std;

typedef boost::shared_ptr<Useroutputinterface> UseroutputinterfacePtr;

// Forward declarations for private classes
template <class T> class Stream_server;
typedef boost::shared_ptr< Stream_server<boost::asio::ip::tcp> >
    TcpServerPtr;
typedef boost::shared_ptr< Stream_server<boost::asio::local::stream_protocol> >
    UnixServerPtr;


class UI_multiplexer: public Useroutputinterface, boost::noncopyable 
{
    typedef UI_multiplexer self;
public:
    friend class Stream_server<boost::asio::ip::tcp>;
    friend class Stream_server<boost::asio::local::stream_protocol>;
    
    /// Singleton
    static self& instance() {
        static self instance;
        return instance;
    }
    
    void listen(boost::asio::ip::tcp::endpoint& endpoint);
    void listen(boost::asio::local::stream_protocol::endpoint& endpoint);
    void run();
    void stop();

protected:
    virtual bool write_to_user_virtual(StringPtr s);
    
private:
    UI_multiplexer();
    virtual ~UI_multiplexer();
    
private:
    vector<UseroutputinterfacePtr> uis;
    boost::asio::io_service io_service;
    vector<TcpServerPtr> tcpServers;
    vector<UnixServerPtr> unixServers;
};

#define UI UI_multiplexer::instance()

#endif /* UI_MULTIPLEXER_H_ */
